df <- read.csv("astronauts.csv")
df <- df %>%
mutate(
age_at_mission = year_of_mission - year_of_birth
) %>%
relocate(age_at_mission, .after = year_of_mission)
head(df)
str(df)
'data.frame': 1277 obs. of 25 variables:
$ id : int 1 2 3 4 5 6 7 8 9 10 ...
$ number : int 1 2 3 3 4 5 5 6 6 7 ...
$ nationwide_number : int 1 2 1 1 2 2 2 4 4 3 ...
$ name : chr "Gagarin, Yuri" "Titov, Gherman" "Glenn, John H., Jr." "Glenn, John H., Jr." ...
$ original_name : chr "ГАГАРИН Юрий Алексеевич" "ТИТОВ Герман Степанович" "Glenn, John H., Jr." "Glenn, John H., Jr." ...
$ sex : chr "male" "male" "male" "male" ...
$ year_of_birth : int 1934 1935 1921 1921 1925 1929 1929 1930 1930 1923 ...
$ nationality : chr "U.S.S.R/Russia" "U.S.S.R/Russia" "U.S." "U.S." ...
$ military_civilian : chr "military" "military" "military" "military" ...
$ selection : chr "TsPK-1" "TsPK-1" "NASA Astronaut Group 1" "NASA Astronaut Group 2" ...
$ year_of_selection : int 1960 1960 1959 1959 1959 1960 1960 1960 1960 1959 ...
$ mission_number : int 1 1 1 2 1 1 2 1 2 1 ...
$ total_number_of_missions: int 1 1 2 2 1 2 2 2 2 3 ...
$ occupation : chr "pilot" "pilot" "pilot" "PSP" ...
$ year_of_mission : int 1961 1961 1962 1998 1962 1962 1970 1962 1974 1962 ...
$ age_at_mission : int 27 26 41 77 37 33 41 32 44 39 ...
$ mission_title : chr "Vostok 1" "Vostok 2" "MA-6" "STS-95" ...
$ ascend_shuttle : chr "Vostok 1" "Vostok 2" "MA-6" "STS-95" ...
$ in_orbit : chr "Vostok 2" "Vostok 2" "MA-6" "STS-95" ...
$ descend_shuttle : chr "Vostok 3" "Vostok 2" "MA-6" "STS-95" ...
$ hours_mission : num 1.77 25 5 213 5 ...
$ total_hrs_sum : num 1.77 25.3 218 218 5 ...
$ eva_instances : int 0 0 0 0 0 0 0 0 0 0 ...
$ eva_hrs_mission : num 0 0 0 0 0 0 0 0 0 0 ...
$ total_eva_hrs : num 0 0 0 0 0 0 0 0 0 0 ...
1. Age & Sex
Visualize the information presented by the year of birth of astronauts. This could be their age when selected, their age during their first mission, or how old they were during their last mission (or all of these). This could also include who were the youngest or oldest astronauts, or which astronauts where active the longest. In addition, use the sex information on the astronauts for further differentiation.
Create 2-3 charts in this section to highlight some important patterns. Make sure to use some variation in the type of visualizations. Briefly discuss which visualization you recommend to your editor and why.
Discuss three specific design choices in these graphs that were influenced by your knowledge of the data visualization principles we discussed in the lectures.
1.1: Atronauts are getting older
plot_1 <- ggplot(data = df, aes(x = year_of_mission, y = age_at_mission, color=sex, shape=sex))
plot_1 +
geom_point(alpha=0.5) +
geom_smooth(se=FALSE) +
geom_label_repel(data=subset(df, age_at_mission < 27 | age_at_mission > 75), aes(label=(name)), show.legend = FALSE) +
labs(
title = "Astronauts are getting older",
subtitle = "Age of astronauts at the time of mission over the years",
x = "Year of the Mission",
y = "Astronaut Age",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)",
color = "Sex",
shape = "Sex"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(hjust = 0, face = "italic"),
plot.background = element_rect(),
legend.key = element_rect(fill = "white", colour = "white"),
legend.background = element_rect()
)

Note: I will follow Tufte minimalistic style and guidance.
In 1.1 I used diffent colours and shapes, as we’ve seen in class, to differantiate between sex.
The whole idea behind to graph is to show how the age of the average astronaut deployed for missions is increasing. Moreover, I’ve included the names of the youngest austronauts (two tied for the youngest), and the oldest, both at the time of mission.
1.2: Grandpas on a Mission
df %>%
arrange(desc(age_at_mission)) %>%
slice(1:10) %>%
ggplot(aes(x=age_at_mission, y= reorder(name, age_at_mission),fill=nationality)) +
geom_col(alpha=0.8) +
geom_text(aes(label = age_at_mission), hjust=1.5) +
scale_fill_brewer(palette = "RdBu") +
labs(
title = "Oldest Astronauts active in a Mission",
x = "Age at the time of the Mission",
y = "",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)",
fill= "Nationality"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.caption = element_text(hjust = -1, face = "italic"),
plot.background = element_rect(),
legend.key = element_rect(fill = "white", colour = "white"),
legend.background = element_rect()
)

In 1.2 I wanted to represent simply the oldest astronauts active in a Mission. I’ve included the nationality to add an additional information. The colors also help to differantiate between the astronauts.
1.3: Ratio of Women per mission by Country
df1 <-
select(df, nationality, sex, name) %>%
add_count(nationality) %>%
rename(total_missions = n) %>%
unique()
df1 %>%
filter(sex == "female") %>%
add_count(name) %>%
group_by(nationality, total_missions) %>%
summarise(number_women = sum(n)) %>%
mutate(ratio = number_women/total_missions) %>%
filter(total_missions>2) %>%
ggplot(aes(y = reorder(nationality, ratio), x = ratio, fill=nationality)) +
geom_col(alpha=0.7) +
geom_text(aes(label = round(ratio, digits = 2), hjust=1.5)) +
scale_fill_brewer(palette = "RdBu") +
labs(
title = "Women per Mission ratio",
subtitle = "How many women per mission by Country?",
x = "Women/Mission Ratio",
y = "",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(hjust = -0.2, face = "italic"),
plot.background = element_rect(),
legend.position = "none"
)
`summarise()` has grouped output by 'nationality'. You can override using the `.groups` argument.

Focusing on sex and the sex gap between austronauts, in 1.3 I wanted to look at the ratio of women per mission by Country. I wanted to look at countries that had at least two mission. It’s important to notice that the country listed is the nationality of the astronaut, which not always corresponds to the country who funded the expedition. So don’t rush blaming the countries!
Editor Suggestion
I suggest to publish the first graph. It’s the one that portraits the highest number of information and it’s also the more graphically pleasing of the three.
2. Nationality
For a long time, space exploration was a duel between two superpowers. But recently, other nations have entered the game as well. Use the information on the nationality of the astronauts to visualize some interesting patterns. Consider, for example, that the composition of shuttle missions has recently become mixed nationalities, something that was absent in earlier times.
Create 1-2 charts in this section to highlight the information on nationality. Make sure to use some variation in the type of visualizations. Briefly discuss which visualization you recommend to your editor and why.
2.1 Space Exploration Missions
plt_1 <- df %>%
group_by(year_of_mission, nationality) %>%
count() %>%
ungroup() %>%
filter(n > 1) %>%
ggplot(aes(x = year_of_mission, y = n, fill = nationality))+
geom_bar(stat = "identity", alpha = 0.8)+
scale_fill_brewer(palette = "RdBu") +
labs(
title = "Space Exploration Missions",
subtitle = "Countries with at least two space explorations per year, by year",
x = "Years",
y = "Number of Missions",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)",
fill = "Nationality"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(hjust = 0, face = "italic"),
plot.background = element_rect(),
legend.key = element_rect(fill = "white", colour = "white"),
legend.background = element_rect()
)
plt_1

In 2.1 I wanted to explore the countries with most exploration missions over the years. To be present in the graph, a country needed to be present in at least two mission in a determined year. The purpose of this choice is to have a cleaner graph with a reasonable number of countries displayed. USSR/Russia and the US are still dominant in the space exploration race.
Editor Suggestion
This is my only graph for this section, but it’s a great graph, you should include it! However, wait to see its interactive version.
3. Space walks
Space walks, or extravehicular activities, are often the highlight of these missions. Wrangle the data to create an overview of cumulative spacewalk records of individual astronauts (i.e. calculate the number and total duration of EVA by astronaut).
Create 1-2 charts in this section to highlight some important patterns. Make sure to use some variation in the type of visualizations. Briefly discuss which visualization you recommend to your editor and why.
space_walks <- df %>%
group_by(name, total_eva_hrs, eva_instances) %>%
summarize(total_eva = sum(eva_instances)) %>%
summarize(total = sum(total_eva)) %>%
mutate(average_eva_time = total_eva_hrs/total) %>%
arrange(desc(total_eva_hrs))
`summarise()` has grouped output by 'name', 'total_eva_hrs'. You can override using the `.groups` argument.
`summarise()` has grouped output by 'name'. You can override using the `.groups` argument.
space_walks_1 <- space_walks[1:10,]
space_walks_1
3.1 Sky-walkers
space_walks_plt_1 <- ggplot(data = space_walks_1, aes(x = total_eva_hrs, y = reorder(name, total_eva_hrs), fill = name))
space_walks_plt_1 +
geom_col(alpha=0.6) +
geom_text(aes(label = total_eva_hrs), hjust=1.5) +
scale_fill_brewer(palette = "RdBu") +
labs(
title = "Sky-walkers",
subtitle = "Top 10 Astronauts with the most extra vehicular hours in history",
x = "Total Extra Vehicular Hours",
y = "",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(hjust = -0.5, face = "italic"),
plot.background = element_rect(),
legend.position = "none"
)

A simple graph of the top ten astronauts with the most extra vehicular hours.
space_walks_2 <- space_walks %>%
arrange(desc(average_eva_time))
space_walks_2 <- space_walks_2[1:10,]
space_walks_2
3.2 Average EVA
space_walks_plt_2 <- ggplot(data = space_walks_2, aes(x = average_eva_time, y = reorder(name, average_eva_time), fill = name))
space_walks_plt_2 +
geom_col(alpha=0.6) +
geom_text(aes(label = round(average_eva_time, digits = 2)), hjust=1.5) +
scale_fill_brewer(palette = "RdBu") +
labs(
title = "How about average extra vehicular hours per mission?",
subtitle = "Top 10 Astronauts with highes EV time per mission",
x = "Average Extra Vehicular Hours per Mission",
y = "",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(hjust = -0.5, face = "italic"),
plot.background = element_rect(),
legend.position = "none"
)

Similar to the one above, this one displays the average EV time per mission. Walheim, second here, is the only one also present in the previous graph with an overall 8th place for the total EV hours.
Editor Suggestion
These two graphs are identical in the layout but display two different interesting statistics for space walks. Choose the one that suits your story best!
4. Your turn to choose
There are few other variables that could make for an interesting story, for example military / civilian status, occupation, shuttle names, mission titles, length in orbit or average length of EVA activities (considering we now have permanent space stations) etc. Select some of these variables to tell a story of your selection.
Create 2-3 charts in this section to highlight some important patterns. Make sure to use some variation in the type of visualizations. Briefly discuss which visualization you recommend to your editor and why.
4.1 I might take a walk
df %>%
ggplot(aes(y=eva_hrs_mission, x=year_of_mission)) +
geom_vline(xintercept=1986) +
geom_vline(xintercept=2001) +
geom_rect(aes(xmin=1986, xmax=2001, ymin=-Inf, ymax=Inf), fill = "bisque", alpha = 0.03) +
geom_label(
label="Mir lifespan",
x=1993.5,
y=70,
label.padding = unit(0.55, "lines"),
label.size = 0.15,
color = "black",
fill="lightcyan"
) +
geom_point(alpha=0.5, color = "cyan3") +
geom_smooth(color = "brown2") +
geom_label_repel(data=subset(df, eva_hrs_mission > 75), aes(label=(ascend_shuttle)), show.legend = FALSE) +
labs(
title = "I might take a walk",
subtitle = "Increase in EV time since permanent space stations",
x = "Year of the Mission",
y = "Total EV hours per Mission",
caption = "Mir is the first relevant orbital space station.\nSoyuz TM-26 is the name of the ascending shuttle. \nSources: Astronaut Database (Stavnichuk & Corlett 2020), Wikipedia: List of space stations"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.subtitle = element_text(size = 10),
plot.caption = element_text(hjust = 0, face = "italic"),
plot.background = element_rect(),
legend.key = element_rect(fill = "white", colour = "white"),
legend.background = element_rect()
)

For this “free to choose” section I selected to plot the increasing time of EV hours per mission. The red regression line clearly shows that the average EV time per mission is increasing. However, the reasoning behind the graph is to show how this increase was accelerated by the creation of orbital space stations. I decided to show the lifespan of Mir, the first relevant space station. Mir was above its predecessors in everything and changed the space exploration forever. It’s during Mir’s lifespan that EV started to become more frequent.
ast_status <- df %>%
group_by(year_of_mission, military_civilian) %>%
count()
ast_status_plt <- ggplot(data = ast_status, aes(x = year_of_mission, y = n, color = military_civilian))
ast_status_plt +
geom_line() +
labs(
title = "Astronauts status",
x = "Year of the Mission",
y = "Number of Astronauts",
caption = "Source: Astronaut Database (Stavnichuk & Corlett 2020)",
color = "Status"
) +
theme_tufte() +
theme(
plot.title = element_text(size = 13, face = "bold"),
plot.caption = element_text(hjust = 0, face = "italic"),
plot.background = element_rect(),
legend.key = element_rect(fill = "white", colour = "white"),
legend.background = element_rect()
)

In this second graph of choice I decided to plot the astronauts’ status, whether military or civilian. I wanted to display this relationship over the years. I believe the line plot is a good choice to highlight the alternation of astronauts’ status, also, I wanted to vary. A bar plot could have been a good alternative.
Editor Suggestion
I’d suggest to publish the one regarding the Mir story. First of all, I consider EV more interesting than the astronauts’ status (which is nonetheless interesting given the recent rise in civilian space exploration missions). Secondly, I believe that including a little bit of history of the space exploration might trigger the reader curiosity about the topic. It’s more likely to be an interesting new notion.
5. Make two plots interactive
Choose 2 of the plots you created above and add interactivity. For at least one of these interactive plots, this should not be done through the use of ggplotly. Briefly describe to the editor why interactivity in these visualizations is particularly helpful for a reader.
5.1 Space Exloration Mission Interactive
ggplotly(plt_1)
I think this graph was perfect for interactivity. First of all, it makes it easier for the reader to get information for the countries that are not predominant. With interactivity, one can easily obtain information for the countries that are underrepresented. Then, it makes it easier to understand the year to which we’re referring and retrieves the exact number of missions for that year.
5.2 Astronauts Status Interactive
plt_5.2 <-
ungroup(ast_status) %>%
plot_ly(y = ~n, x = ~year_of_mission, color = ~military_civilian, type = "scatter", mode = "lines") %>%
layout(
title = "Astronauts status",
xaxis = list(title = "Year of the Mission"),
yaxis = list(title = "Number of Astronauts")
)
plt_5.2
I believe the interactivity makes it easier to confront the information present in this graph. Since the purpose of this graph is a comparison, with the cursor one can easily make compare the exact number for the two statuses being sure that she’s confronting the same year.
6. Data Table
To allow the reader to explore the record holding achievements of astronauts, aggregate the data by astronaut. Include the total number of missions, the total mission time, and anything else you consider useful to share and add a data table to the output. Make sure the columns are clearly labeled. Select the appropriate options for the data table (e.g. search bar, sorting, column filters, in-line visualizations etc.). Suggest to the editor which kind of information you would like to provide in a data table and why.
6.1 Data Table
data_table <- df %>%
select(name, sex, year_of_birth, nationality, total_number_of_missions, total_hrs_sum, total_eva_hrs) %>%
unique() %>%
arrange(name)
datatable(data_table,
filter = 'top',
options = list(pageLength = 5, autoWidth = TRUE),
colnames = c('Name', 'Sex', 'Year of Birth', 'Nationality', 'Total Number of Missions', 'Total hours of Mission', 'Total Extra Vehicular hours'),
caption = htmltools::tags$caption(
style = 'caption-side: bottom; text-align: left;', htmltools::em('Source: Astronaut Database (Stavnichuk & Corlett 2020)')
)
)
The data table is extremely useful to retrieve information. The filter option, for example, helps the reader to navigate and select data according to his interest. If one wants to retrieve all the italian astronauts of the dataset, she can easily type “Italy” under the Nationality column, and then reorganize the data to her preference. For example, which italian astronaut had more mission hours? Type “Italy” under the Nationality column and then reorganize by “Total hours of Mission.”
This data table provides information about the Name, Sex, Year of Birth, Nationality, Total Number of Mission, Total hours of Mission, Total Etra Vehicular hours, for all astronauts present in the dataset.
LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpemF0aW9uIEhXIDEiCmF1dGhvcjogIkRhdmlkZSBWYWNjYXJpIgpkYXRlOiAiMi8xNy8yMDIxIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IFRSVUUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KGdndGhlbWVzKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShEVCkKYGBgCgpgYGB7cn0KZGYgPC0gcmVhZC5jc3YoImFzdHJvbmF1dHMuY3N2IikKYGBgCmBgYHtyfQpkZiA8LSBkZiAlPiUKICBtdXRhdGUoCiAgICBhZ2VfYXRfbWlzc2lvbiA9IHllYXJfb2ZfbWlzc2lvbiAtIHllYXJfb2ZfYmlydGgKICApICU+JQogIHJlbG9jYXRlKGFnZV9hdF9taXNzaW9uLCAuYWZ0ZXIgPSB5ZWFyX29mX21pc3Npb24pCgpoZWFkKGRmKQpgYGAKYGBge3J9CnN0cihkZikKYGBgCl9fXwojIDEuIEFnZSAmIFNleAoKVmlzdWFsaXplIHRoZSBpbmZvcm1hdGlvbiBwcmVzZW50ZWQgYnkgdGhlIHllYXIgb2YgYmlydGggb2YgYXN0cm9uYXV0cy4gVGhpcyBjb3VsZCBiZSB0aGVpciBhZ2Ugd2hlbiBzZWxlY3RlZCwgdGhlaXIgYWdlIGR1cmluZyB0aGVpciBmaXJzdCBtaXNzaW9uLCBvciBob3cgb2xkIHRoZXkgd2VyZSBkdXJpbmcgdGhlaXIgbGFzdCBtaXNzaW9uIChvciBhbGwgb2YgdGhlc2UpLiBUaGlzIGNvdWxkIGFsc28gaW5jbHVkZSB3aG8gd2VyZSB0aGUgeW91bmdlc3Qgb3Igb2xkZXN0IGFzdHJvbmF1dHMsIG9yIHdoaWNoIGFzdHJvbmF1dHMgd2hlcmUgYWN0aXZlIHRoZSBsb25nZXN0LiBJbiBhZGRpdGlvbiwgdXNlIHRoZSBzZXggaW5mb3JtYXRpb24gb24gdGhlIGFzdHJvbmF1dHMgZm9yIGZ1cnRoZXIgZGlmZmVyZW50aWF0aW9uLgoKQ3JlYXRlIDItMyBjaGFydHMgaW4gdGhpcyBzZWN0aW9uIHRvIGhpZ2hsaWdodCBzb21lIGltcG9ydGFudCBwYXR0ZXJucy4gTWFrZSBzdXJlIHRvIHVzZSBzb21lIHZhcmlhdGlvbiBpbiB0aGUgdHlwZSBvZiB2aXN1YWxpemF0aW9ucy4gQnJpZWZseSBkaXNjdXNzIHdoaWNoIHZpc3VhbGl6YXRpb24geW91IHJlY29tbWVuZCB0byB5b3VyIGVkaXRvciBhbmQgd2h5LgoKRGlzY3VzcyB0aHJlZSBzcGVjaWZpYyBkZXNpZ24gY2hvaWNlcyBpbiB0aGVzZSBncmFwaHMgdGhhdCB3ZXJlIGluZmx1ZW5jZWQgYnkgeW91ciBrbm93bGVkZ2Ugb2YgdGhlIGRhdGEgdmlzdWFsaXphdGlvbiBwcmluY2lwbGVzIHdlIGRpc2N1c3NlZCBpbiB0aGUgbGVjdHVyZXMuCgojIyAxLjE6IEF0cm9uYXV0cyBhcmUgZ2V0dGluZyBvbGRlcgpgYGB7cn0KcGxvdF8xIDwtIGdncGxvdChkYXRhID0gZGYsIGFlcyh4ID0geWVhcl9vZl9taXNzaW9uLCB5ID0gYWdlX2F0X21pc3Npb24sIGNvbG9yPXNleCwgc2hhcGU9c2V4KSkKcGxvdF8xICsKICAKICBnZW9tX3BvaW50KGFscGhhPTAuNSkgKyAKICBnZW9tX3Ntb290aChzZT1GQUxTRSkgKyAKICBnZW9tX2xhYmVsX3JlcGVsKGRhdGE9c3Vic2V0KGRmLCBhZ2VfYXRfbWlzc2lvbiA8IDI3IHwgYWdlX2F0X21pc3Npb24gPiA3NSksIGFlcyhsYWJlbD0obmFtZSkpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgCiAgCiAgbGFicygKICAgIHRpdGxlID0gIkFzdHJvbmF1dHMgYXJlIGdldHRpbmcgb2xkZXIiLAogICAgc3VidGl0bGUgPSAiQWdlIG9mIGFzdHJvbmF1dHMgYXQgdGhlIHRpbWUgb2YgbWlzc2lvbiBvdmVyIHRoZSB5ZWFycyIsCiAgICB4ID0gIlllYXIgb2YgdGhlIE1pc3Npb24iLCAKICAgIHkgPSAiQXN0cm9uYXV0IEFnZSIsCiAgICBjYXB0aW9uID0gIlNvdXJjZTogQXN0cm9uYXV0IERhdGFiYXNlIChTdGF2bmljaHVrICYgQ29ybGV0dCAyMDIwKSIsCiAgICBjb2xvciA9ICJTZXgiLAogICAgc2hhcGUgPSAiU2V4IgogICAgKSArIAogIAogIHRoZW1lX3R1ZnRlKCkgKyAKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIGZhY2UgPSAiaXRhbGljIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKSwKICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ICJ3aGl0ZSIpLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKQogICAgKQpgYGAKCioqTm90ZSoqOiBJIHdpbGwgZm9sbG93IFR1ZnRlIG1pbmltYWxpc3RpYyBzdHlsZSBhbmQgZ3VpZGFuY2UuCgpJbiAxLjEgSSB1c2VkIGRpZmZlbnQgY29sb3VycyBhbmQgc2hhcGVzLCBhcyB3ZSd2ZSBzZWVuIGluIGNsYXNzLCB0byBkaWZmZXJhbnRpYXRlIGJldHdlZW4gc2V4LiAgClRoZSB3aG9sZSBpZGVhIGJlaGluZCB0byBncmFwaCBpcyB0byBzaG93IGhvdyB0aGUgYWdlIG9mIHRoZSBhdmVyYWdlIGFzdHJvbmF1dCBkZXBsb3llZCBmb3IgbWlzc2lvbnMgaXMgaW5jcmVhc2luZy4gTW9yZW92ZXIsIEkndmUgaW5jbHVkZWQgdGhlIG5hbWVzIG9mIHRoZSB5b3VuZ2VzdCBhdXN0cm9uYXV0cyAodHdvIHRpZWQgZm9yIHRoZSB5b3VuZ2VzdCksIGFuZCB0aGUgb2xkZXN0LCBib3RoIGF0IHRoZSB0aW1lIG9mIG1pc3Npb24uCgojIyAxLjI6IEdyYW5kcGFzIG9uIGEgTWlzc2lvbgpgYGB7cn0KZGYgJT4lCiAgYXJyYW5nZShkZXNjKGFnZV9hdF9taXNzaW9uKSkgJT4lCiAgc2xpY2UoMToxMCkgJT4lCiAgCiAgZ2dwbG90KGFlcyh4PWFnZV9hdF9taXNzaW9uLCB5PSByZW9yZGVyKG5hbWUsIGFnZV9hdF9taXNzaW9uKSxmaWxsPW5hdGlvbmFsaXR5KSkgKwogIGdlb21fY29sKGFscGhhPTAuOCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBhZ2VfYXRfbWlzc2lvbiksIGhqdXN0PTEuNSkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUmRCdSIpICsKICAKICBsYWJzKAogICAgdGl0bGUgPSAiT2xkZXN0IEFzdHJvbmF1dHMgYWN0aXZlIGluIGEgTWlzc2lvbiIsCiAgICB4ID0gIkFnZSBhdCB0aGUgdGltZSBvZiB0aGUgTWlzc2lvbiIsCiAgICB5ID0gIiIsCiAgICBjYXB0aW9uID0gIlNvdXJjZTogQXN0cm9uYXV0IERhdGFiYXNlIChTdGF2bmljaHVrICYgQ29ybGV0dCAyMDIwKSIsCiAgICBmaWxsPSAiTmF0aW9uYWxpdHkiCiAgICApICsgCiAgCiAgdGhlbWVfdHVmdGUoKSArIAogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLTEsIGZhY2UgPSAiaXRhbGljIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKSwKICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ICJ3aGl0ZSIpLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKQogICAgKQpgYGAKCkluIDEuMiBJIHdhbnRlZCB0byByZXByZXNlbnQgc2ltcGx5IHRoZSBvbGRlc3QgYXN0cm9uYXV0cyBhY3RpdmUgaW4gYSBNaXNzaW9uLiBJJ3ZlIGluY2x1ZGVkIHRoZSBuYXRpb25hbGl0eSB0byBhZGQgYW4gYWRkaXRpb25hbCBpbmZvcm1hdGlvbi4gVGhlIGNvbG9ycyBhbHNvIGhlbHAgdG8gZGlmZmVyYW50aWF0ZSBiZXR3ZWVuIHRoZSBhc3Ryb25hdXRzLgoKIyMgMS4zOiBSYXRpbyBvZiBXb21lbiBwZXIgbWlzc2lvbiBieSBDb3VudHJ5CmBgYHtyfQpkZjEgPC0KICBzZWxlY3QoZGYsIG5hdGlvbmFsaXR5LCBzZXgsIG5hbWUpICU+JQogIGFkZF9jb3VudChuYXRpb25hbGl0eSkgJT4lCiAgcmVuYW1lKHRvdGFsX21pc3Npb25zID0gbikgJT4lCiAgdW5pcXVlKCkKIApkZjEgJT4lCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lCiAgYWRkX2NvdW50KG5hbWUpICU+JQogIGdyb3VwX2J5KG5hdGlvbmFsaXR5LCB0b3RhbF9taXNzaW9ucykgJT4lCiAgc3VtbWFyaXNlKG51bWJlcl93b21lbiA9IHN1bShuKSkgJT4lCiAgbXV0YXRlKHJhdGlvID0gbnVtYmVyX3dvbWVuL3RvdGFsX21pc3Npb25zKSAlPiUKICBmaWx0ZXIodG90YWxfbWlzc2lvbnM+MikgJT4lCiAgCiAgZ2dwbG90KGFlcyh5ID0gcmVvcmRlcihuYXRpb25hbGl0eSwgcmF0aW8pLCB4ID0gcmF0aW8sIGZpbGw9bmF0aW9uYWxpdHkpKSArIAogIGdlb21fY29sKGFscGhhPTAuNykgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChyYXRpbywgZGlnaXRzID0gMiksIGhqdXN0PTEuNSkpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiKSArCgogIGxhYnMoCiAgICB0aXRsZSA9ICJXb21lbiBwZXIgTWlzc2lvbiByYXRpbyIsCiAgICBzdWJ0aXRsZSA9ICJIb3cgbWFueSB3b21lbiBwZXIgbWlzc2lvbiBieSBDb3VudHJ5PyIsCiAgICB4ID0gIldvbWVuL01pc3Npb24gUmF0aW8iLAogICAgeSA9ICIiLAogICAgY2FwdGlvbiA9ICJTb3VyY2U6IEFzdHJvbmF1dCBEYXRhYmFzZSAoU3Rhdm5pY2h1ayAmIENvcmxldHQgMjAyMCkiCiAgICApICsgCiAgCiAgdGhlbWVfdHVmdGUoKSArIAogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLTAuMiwgZmFjZSA9ICJpdGFsaWMiKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCgpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiCiAgICApCmBgYAoKRm9jdXNpbmcgb24gc2V4IGFuZCB0aGUgc2V4IGdhcCBiZXR3ZWVuIGF1c3Ryb25hdXRzLCBpbiAxLjMgSSB3YW50ZWQgdG8gbG9vayBhdCB0aGUgcmF0aW8gb2Ygd29tZW4gcGVyIG1pc3Npb24gYnkgQ291bnRyeS4gSSB3YW50ZWQgdG8gbG9vayBhdCBjb3VudHJpZXMgdGhhdCBoYWQgYXQgbGVhc3QgdHdvIG1pc3Npb24uIEl0J3MgaW1wb3J0YW50IHRvIG5vdGljZSB0aGF0IHRoZSBjb3VudHJ5IGxpc3RlZCBpcyB0aGUgbmF0aW9uYWxpdHkgb2YgdGhlIGFzdHJvbmF1dCwgd2hpY2ggbm90IGFsd2F5cyBjb3JyZXNwb25kcyB0byB0aGUgY291bnRyeSB3aG8gZnVuZGVkIHRoZSBleHBlZGl0aW9uLiBTbyBkb24ndCBydXNoIGJsYW1pbmcgdGhlIGNvdW50cmllcyEKCioqRWRpdG9yIFN1Z2dlc3Rpb24qKiAgCkkgc3VnZ2VzdCB0byBwdWJsaXNoIHRoZSBmaXJzdCBncmFwaC4gSXQncyB0aGUgb25lIHRoYXQgcG9ydHJhaXRzIHRoZSBoaWdoZXN0IG51bWJlciBvZiBpbmZvcm1hdGlvbiBhbmQgaXQncyBhbHNvIHRoZSBtb3JlIGdyYXBoaWNhbGx5IHBsZWFzaW5nIG9mIHRoZSB0aHJlZS4KCl9fXwojIDIuIE5hdGlvbmFsaXR5CgpGb3IgYSBsb25nIHRpbWUsIHNwYWNlIGV4cGxvcmF0aW9uIHdhcyBhIGR1ZWwgYmV0d2VlbiB0d28gc3VwZXJwb3dlcnMuIEJ1dCByZWNlbnRseSwgb3RoZXIgbmF0aW9ucyBoYXZlIGVudGVyZWQgdGhlIGdhbWUgYXMgd2VsbC4gVXNlIHRoZSBpbmZvcm1hdGlvbiBvbiB0aGUgbmF0aW9uYWxpdHkgb2YgdGhlIGFzdHJvbmF1dHMgdG8gdmlzdWFsaXplIHNvbWUgaW50ZXJlc3RpbmcgcGF0dGVybnMuIENvbnNpZGVyLCBmb3IgZXhhbXBsZSwgdGhhdCB0aGUgY29tcG9zaXRpb24gb2Ygc2h1dHRsZSBtaXNzaW9ucyBoYXMgcmVjZW50bHkgYmVjb21lIG1peGVkIG5hdGlvbmFsaXRpZXMsIHNvbWV0aGluZyB0aGF0IHdhcyBhYnNlbnQgaW4gZWFybGllciB0aW1lcy4KCkNyZWF0ZSAxLTIgY2hhcnRzIGluIHRoaXMgc2VjdGlvbiB0byBoaWdobGlnaHQgdGhlIGluZm9ybWF0aW9uIG9uIG5hdGlvbmFsaXR5LiBNYWtlIHN1cmUgdG8gdXNlIHNvbWUgdmFyaWF0aW9uIGluIHRoZSB0eXBlIG9mIHZpc3VhbGl6YXRpb25zLiBCcmllZmx5IGRpc2N1c3Mgd2hpY2ggdmlzdWFsaXphdGlvbiB5b3UgcmVjb21tZW5kIHRvIHlvdXIgZWRpdG9yIGFuZCB3aHkuCgojIyAyLjEgU3BhY2UgRXhwbG9yYXRpb24gTWlzc2lvbnMKYGBge3J9CnBsdF8xIDwtIGRmICU+JQogIGdyb3VwX2J5KHllYXJfb2ZfbWlzc2lvbiwgbmF0aW9uYWxpdHkpICU+JQogIGNvdW50KCkgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihuID4gMSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhcl9vZl9taXNzaW9uLCB5ID0gbiwgZmlsbCA9IG5hdGlvbmFsaXR5KSkrCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGFscGhhID0gMC44KSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiKSArCgogIGxhYnMoCiAgdGl0bGUgPSAiU3BhY2UgRXhwbG9yYXRpb24gTWlzc2lvbnMiLCAKICBzdWJ0aXRsZSA9ICJDb3VudHJpZXMgd2l0aCBhdCBsZWFzdCB0d28gc3BhY2UgZXhwbG9yYXRpb25zIHBlciB5ZWFyLCBieSB5ZWFyIiwKICB4ID0gIlllYXJzIiwKICB5ID0gIk51bWJlciBvZiBNaXNzaW9ucyIsCiAgY2FwdGlvbiA9ICJTb3VyY2U6IEFzdHJvbmF1dCBEYXRhYmFzZSAoU3Rhdm5pY2h1ayAmIENvcmxldHQgMjAyMCkiLAogIGZpbGwgPSAiTmF0aW9uYWxpdHkiCiAgICApICsgCiAgCiAgdGhlbWVfdHVmdGUoKSArIAogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgZmFjZSA9ICJpdGFsaWMiKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCgpLAogICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3VyID0gIndoaXRlIiksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCgpCiAgICApCgpwbHRfMQpgYGAKCkluIDIuMSBJIHdhbnRlZCB0byBleHBsb3JlIHRoZSBjb3VudHJpZXMgd2l0aCBtb3N0IGV4cGxvcmF0aW9uIG1pc3Npb25zIG92ZXIgdGhlIHllYXJzLiBUbyBiZSBwcmVzZW50IGluIHRoZSBncmFwaCwgYSBjb3VudHJ5IG5lZWRlZCB0byBiZSBwcmVzZW50IGluIGF0IGxlYXN0IHR3byBtaXNzaW9uIGluIGEgZGV0ZXJtaW5lZCB5ZWFyLiBUaGUgcHVycG9zZSBvZiB0aGlzIGNob2ljZSBpcyB0byBoYXZlIGEgY2xlYW5lciBncmFwaCB3aXRoIGEgcmVhc29uYWJsZSBudW1iZXIgb2YgY291bnRyaWVzIGRpc3BsYXllZC4gVVNTUi9SdXNzaWEgYW5kIHRoZSBVUyBhcmUgc3RpbGwgZG9taW5hbnQgaW4gdGhlIHNwYWNlIGV4cGxvcmF0aW9uIHJhY2UuCgoqKkVkaXRvciBTdWdnZXN0aW9uKiogIApUaGlzIGlzIG15IG9ubHkgZ3JhcGggZm9yIHRoaXMgc2VjdGlvbiwgYnV0IGl0J3MgYSBncmVhdCBncmFwaCwgeW91IHNob3VsZCBpbmNsdWRlIGl0ISBIb3dldmVyLCB3YWl0IHRvIHNlZSBpdHMgaW50ZXJhY3RpdmUgdmVyc2lvbi4KCl9fXwojIDMuIFNwYWNlIHdhbGtzCgpTcGFjZSB3YWxrcywgb3IgZXh0cmF2ZWhpY3VsYXIgYWN0aXZpdGllcywgYXJlIG9mdGVuIHRoZSBoaWdobGlnaHQgb2YgdGhlc2UgbWlzc2lvbnMuIFdyYW5nbGUgdGhlIGRhdGEgdG8gY3JlYXRlIGFuIG92ZXJ2aWV3IG9mIGN1bXVsYXRpdmUgc3BhY2V3YWxrIHJlY29yZHMgb2YgaW5kaXZpZHVhbCBhc3Ryb25hdXRzIChpLmUuIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIGFuZCB0b3RhbCBkdXJhdGlvbiBvZiBFVkEgYnkgYXN0cm9uYXV0KS4KCkNyZWF0ZSAxLTIgY2hhcnRzIGluIHRoaXMgc2VjdGlvbiB0byBoaWdobGlnaHQgc29tZSBpbXBvcnRhbnQgcGF0dGVybnMuIE1ha2Ugc3VyZSB0byB1c2Ugc29tZSB2YXJpYXRpb24gaW4gdGhlIHR5cGUgb2YgdmlzdWFsaXphdGlvbnMuIEJyaWVmbHkgZGlzY3VzcyB3aGljaCB2aXN1YWxpemF0aW9uIHlvdSByZWNvbW1lbmQgdG8geW91ciBlZGl0b3IgYW5kIHdoeS4KCmBgYHtyfQpzcGFjZV93YWxrcyA8LSBkZiAlPiUKICBncm91cF9ieShuYW1lLCB0b3RhbF9ldmFfaHJzLCBldmFfaW5zdGFuY2VzKSAlPiUKICBzdW1tYXJpemUodG90YWxfZXZhID0gc3VtKGV2YV9pbnN0YW5jZXMpKSAlPiUKICBzdW1tYXJpemUodG90YWwgPSBzdW0odG90YWxfZXZhKSkgJT4lCiAgbXV0YXRlKGF2ZXJhZ2VfZXZhX3RpbWUgPSB0b3RhbF9ldmFfaHJzL3RvdGFsKSAlPiUKICBhcnJhbmdlKGRlc2ModG90YWxfZXZhX2hycykpCmBgYAoKYGBge3J9CnNwYWNlX3dhbGtzXzEgPC0gc3BhY2Vfd2Fsa3NbMToxMCxdCnNwYWNlX3dhbGtzXzEKYGBgCiMjIDMuMSBTa3ktd2Fsa2VycwpgYGB7cn0Kc3BhY2Vfd2Fsa3NfcGx0XzEgPC0gZ2dwbG90KGRhdGEgPSBzcGFjZV93YWxrc18xLCBhZXMoeCA9IHRvdGFsX2V2YV9ocnMsIHkgPSByZW9yZGVyKG5hbWUsIHRvdGFsX2V2YV9ocnMpLCBmaWxsID0gbmFtZSkpCnNwYWNlX3dhbGtzX3BsdF8xICsKCiAgZ2VvbV9jb2woYWxwaGE9MC42KSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHRvdGFsX2V2YV9ocnMpLCBoanVzdD0xLjUpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJkQnUiKSArCiAgCiAgbGFicygKICB0aXRsZSA9ICJTa3ktd2Fsa2VycyIsCiAgc3VidGl0bGUgPSAiVG9wIDEwIEFzdHJvbmF1dHMgd2l0aCB0aGUgbW9zdCBleHRyYSB2ZWhpY3VsYXIgaG91cnMgaW4gaGlzdG9yeSIsCiAgeCA9ICJUb3RhbCBFeHRyYSBWZWhpY3VsYXIgSG91cnMiLAogIHkgPSAiIiwKICBjYXB0aW9uID0gIlNvdXJjZTogQXN0cm9uYXV0IERhdGFiYXNlIChTdGF2bmljaHVrICYgQ29ybGV0dCAyMDIwKSIKICAgICkgKyAKICAKICB0aGVtZV90dWZ0ZSgpICsgCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMywgZmFjZSA9ICJib2xkIiksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoaGp1c3QgPSAtMC41LCBmYWNlID0gIml0YWxpYyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIKICAgICkKYGBgCgpBIHNpbXBsZSBncmFwaCBvZiB0aGUgdG9wIHRlbiBhc3Ryb25hdXRzIHdpdGggdGhlIG1vc3QgZXh0cmEgdmVoaWN1bGFyIGhvdXJzLgoKYGBge3J9CnNwYWNlX3dhbGtzXzIgPC0gc3BhY2Vfd2Fsa3MgJT4lCiAgYXJyYW5nZShkZXNjKGF2ZXJhZ2VfZXZhX3RpbWUpKQpzcGFjZV93YWxrc18yIDwtIHNwYWNlX3dhbGtzXzJbMToxMCxdCnNwYWNlX3dhbGtzXzIKYGBgCiMjIDMuMiBBdmVyYWdlIEVWQQpgYGB7cn0Kc3BhY2Vfd2Fsa3NfcGx0XzIgPC0gZ2dwbG90KGRhdGEgPSBzcGFjZV93YWxrc18yLCBhZXMoeCA9IGF2ZXJhZ2VfZXZhX3RpbWUsIHkgPSByZW9yZGVyKG5hbWUsIGF2ZXJhZ2VfZXZhX3RpbWUpLCBmaWxsID0gbmFtZSkpCnNwYWNlX3dhbGtzX3BsdF8yICsKCiAgZ2VvbV9jb2woYWxwaGE9MC42KSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGF2ZXJhZ2VfZXZhX3RpbWUsIGRpZ2l0cyA9IDIpKSwgaGp1c3Q9MS41KSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJSZEJ1IikgKwogIAogIGxhYnMoCiAgdGl0bGUgPSAiSG93IGFib3V0IGF2ZXJhZ2UgZXh0cmEgdmVoaWN1bGFyIGhvdXJzIHBlciBtaXNzaW9uPyIsCiAgc3VidGl0bGUgPSAiVG9wIDEwIEFzdHJvbmF1dHMgd2l0aCBoaWdoZXMgRVYgdGltZSBwZXIgbWlzc2lvbiIsCiAgeCA9ICJBdmVyYWdlIEV4dHJhIFZlaGljdWxhciBIb3VycyBwZXIgTWlzc2lvbiIsCiAgeSA9ICIiLAogIGNhcHRpb24gPSAiU291cmNlOiBBc3Ryb25hdXQgRGF0YWJhc2UgKFN0YXZuaWNodWsgJiBDb3JsZXR0IDIwMjApIgogICAgKSArIAogIAogIHRoZW1lX3R1ZnRlKCkgKyAKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC0wLjUsIGZhY2UgPSAiaXRhbGljIiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICAgKQpgYGAKClNpbWlsYXIgdG8gdGhlIG9uZSBhYm92ZSwgdGhpcyBvbmUgZGlzcGxheXMgdGhlIGF2ZXJhZ2UgRVYgdGltZSBwZXIgbWlzc2lvbi4KV2FsaGVpbSwgc2Vjb25kIGhlcmUsIGlzIHRoZSBvbmx5IG9uZSBhbHNvIHByZXNlbnQgaW4gdGhlIHByZXZpb3VzIGdyYXBoIHdpdGggYW4gb3ZlcmFsbCA4dGggcGxhY2UgZm9yIHRoZSB0b3RhbCBFViBob3Vycy4KCioqRWRpdG9yIFN1Z2dlc3Rpb24qKiAgClRoZXNlIHR3byBncmFwaHMgYXJlIGlkZW50aWNhbCBpbiB0aGUgbGF5b3V0IGJ1dCBkaXNwbGF5IHR3byBkaWZmZXJlbnQgaW50ZXJlc3Rpbmcgc3RhdGlzdGljcyBmb3Igc3BhY2Ugd2Fsa3MuIENob29zZSB0aGUgb25lIHRoYXQgc3VpdHMgeW91ciBzdG9yeSBiZXN0IQoKX19fCiMgNC4gWW91ciB0dXJuIHRvIGNob29zZQoKVGhlcmUgYXJlIGZldyBvdGhlciB2YXJpYWJsZXMgdGhhdCBjb3VsZCBtYWtlIGZvciBhbiBpbnRlcmVzdGluZyBzdG9yeSwgZm9yIGV4YW1wbGUgbWlsaXRhcnkgLyBjaXZpbGlhbiBzdGF0dXMsIG9jY3VwYXRpb24sIHNodXR0bGUgbmFtZXMsIG1pc3Npb24gdGl0bGVzLCBsZW5ndGggaW4gb3JiaXQgb3IgYXZlcmFnZSBsZW5ndGggb2YgRVZBIGFjdGl2aXRpZXMgKGNvbnNpZGVyaW5nIHdlIG5vdyBoYXZlIHBlcm1hbmVudCBzcGFjZSBzdGF0aW9ucykgZXRjLiBTZWxlY3Qgc29tZSBvZiB0aGVzZSB2YXJpYWJsZXMgdG8gdGVsbCBhIHN0b3J5IG9mIHlvdXIgc2VsZWN0aW9uLgoKQ3JlYXRlIDItMyBjaGFydHMgaW4gdGhpcyBzZWN0aW9uIHRvIGhpZ2hsaWdodCBzb21lIGltcG9ydGFudCBwYXR0ZXJucy4gTWFrZSBzdXJlIHRvIHVzZSBzb21lIHZhcmlhdGlvbiBpbiB0aGUgdHlwZSBvZiB2aXN1YWxpemF0aW9ucy4gQnJpZWZseSBkaXNjdXNzIHdoaWNoIHZpc3VhbGl6YXRpb24geW91IHJlY29tbWVuZCB0byB5b3VyIGVkaXRvciBhbmQgd2h5LgoKIyMgNC4xIEkgbWlnaHQgdGFrZSBhIHdhbGsKYGBge3J9CmRmICU+JQogIAogIGdncGxvdChhZXMoeT1ldmFfaHJzX21pc3Npb24sIHg9eWVhcl9vZl9taXNzaW9uKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdD0xOTg2KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTIwMDEpICsKICBnZW9tX3JlY3QoYWVzKHhtaW49MTk4NiwgeG1heD0yMDAxLCB5bWluPS1JbmYsIHltYXg9SW5mKSwgZmlsbCA9ICJiaXNxdWUiLCBhbHBoYSA9IDAuMDMpICsKICBnZW9tX2xhYmVsKAogICAgbGFiZWw9Ik1pciBsaWZlc3BhbiIsIAogICAgeD0xOTkzLjUsCiAgICB5PTcwLAogICAgbGFiZWwucGFkZGluZyA9IHVuaXQoMC41NSwgImxpbmVzIiksCiAgICBsYWJlbC5zaXplID0gMC4xNSwKICAgIGNvbG9yID0gImJsYWNrIiwKICAgIGZpbGw9ImxpZ2h0Y3lhbiIKICApICsKICBnZW9tX3BvaW50KGFscGhhPTAuNSwgY29sb3IgPSAiY3lhbjMiKSArIAogIGdlb21fc21vb3RoKGNvbG9yID0gImJyb3duMiIpICsKICBnZW9tX2xhYmVsX3JlcGVsKGRhdGE9c3Vic2V0KGRmLCBldmFfaHJzX21pc3Npb24gPiA3NSksIGFlcyhsYWJlbD0oYXNjZW5kX3NodXR0bGUpKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIAogIGxhYnMoCiAgICB0aXRsZSA9ICJJIG1pZ2h0IHRha2UgYSB3YWxrIiwKICAgIHN1YnRpdGxlID0gIkluY3JlYXNlIGluIEVWIHRpbWUgc2luY2UgcGVybWFuZW50IHNwYWNlIHN0YXRpb25zIiwKICAgIHggPSAiWWVhciBvZiB0aGUgTWlzc2lvbiIsIAogICAgeSA9ICJUb3RhbCBFViBob3VycyBwZXIgTWlzc2lvbiIsCiAgICBjYXB0aW9uID0gIk1pciBpcyB0aGUgZmlyc3QgcmVsZXZhbnQgb3JiaXRhbCBzcGFjZSBzdGF0aW9uLlxuU295dXogVE0tMjYgaXMgdGhlIG5hbWUgb2YgdGhlIGFzY2VuZGluZyBzaHV0dGxlLiBcblNvdXJjZXM6IEFzdHJvbmF1dCBEYXRhYmFzZSAoU3Rhdm5pY2h1ayAmIENvcmxldHQgMjAyMCksIFdpa2lwZWRpYTogTGlzdCBvZiBzcGFjZSBzdGF0aW9ucyIKICAgICkgKyAKICAKICB0aGVtZV90dWZ0ZSgpICsgCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMywgZmFjZSA9ICJib2xkIiksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLCBmYWNlID0gIml0YWxpYyIpLAogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCksCiAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvdXIgPSAid2hpdGUiKSwKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCkKICAgICkKYGBgCgpGb3IgdGhpcyAiZnJlZSB0byBjaG9vc2UiIHNlY3Rpb24gSSBzZWxlY3RlZCB0byBwbG90IHRoZSBpbmNyZWFzaW5nIHRpbWUgb2YgRVYgaG91cnMgcGVyIG1pc3Npb24uIFRoZSByZWQgcmVncmVzc2lvbiBsaW5lIGNsZWFybHkgc2hvd3MgdGhhdCB0aGUgYXZlcmFnZSBFViB0aW1lIHBlciBtaXNzaW9uIGlzIGluY3JlYXNpbmcuIEhvd2V2ZXIsIHRoZSByZWFzb25pbmcgYmVoaW5kIHRoZSBncmFwaCBpcyB0byBzaG93IGhvdyB0aGlzIGluY3JlYXNlIHdhcyBhY2NlbGVyYXRlZCBieSB0aGUgY3JlYXRpb24gb2Ygb3JiaXRhbCBzcGFjZSBzdGF0aW9ucy4gSSBkZWNpZGVkIHRvIHNob3cgdGhlIGxpZmVzcGFuIG9mIFtNaXJdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xpc3Rfb2Zfc3BhY2Vfc3RhdGlvbnMpLCB0aGUgZmlyc3QgcmVsZXZhbnQgc3BhY2Ugc3RhdGlvbi4gTWlyIHdhcyBhYm92ZSBpdHMgcHJlZGVjZXNzb3JzIGluIGV2ZXJ5dGhpbmcgYW5kIGNoYW5nZWQgdGhlIHNwYWNlIGV4cGxvcmF0aW9uIGZvcmV2ZXIuIEl0J3MgZHVyaW5nIE1pcidzIGxpZmVzcGFuIHRoYXQgRVYgc3RhcnRlZCB0byBiZWNvbWUgbW9yZSBmcmVxdWVudC4KCmBgYHtyfQphc3Rfc3RhdHVzIDwtIGRmICU+JQogIGdyb3VwX2J5KHllYXJfb2ZfbWlzc2lvbiwgbWlsaXRhcnlfY2l2aWxpYW4pICU+JQogIGNvdW50KCkKYGBgCgoKYGBge3J9CmFzdF9zdGF0dXNfcGx0IDwtIGdncGxvdChkYXRhID0gYXN0X3N0YXR1cywgYWVzKHggPSB5ZWFyX29mX21pc3Npb24sIHkgPSBuLCBjb2xvciA9IG1pbGl0YXJ5X2NpdmlsaWFuKSkKCmFzdF9zdGF0dXNfcGx0ICsKICAKICBnZW9tX2xpbmUoKSArCiAgCiAgbGFicygKICAgIHRpdGxlID0gIkFzdHJvbmF1dHMgc3RhdHVzIiwKICAgIHggPSAiWWVhciBvZiB0aGUgTWlzc2lvbiIsIAogICAgeSA9ICJOdW1iZXIgb2YgQXN0cm9uYXV0cyIsCiAgICBjYXB0aW9uID0gIlNvdXJjZTogQXN0cm9uYXV0IERhdGFiYXNlIChTdGF2bmljaHVrICYgQ29ybGV0dCAyMDIwKSIsCiAgICBjb2xvciA9ICJTdGF0dXMiCiAgICApICsgCiAgCiAgCiAgdGhlbWVfdHVmdGUoKSArIAogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIGZhY2UgPSAiYm9sZCIpLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgZmFjZSA9ICJpdGFsaWMiKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCgpLAogICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3VyID0gIndoaXRlIiksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCgpCiAgICApCmBgYAoKSW4gdGhpcyBzZWNvbmQgZ3JhcGggb2YgY2hvaWNlIEkgZGVjaWRlZCB0byBwbG90IHRoZSBhc3Ryb25hdXRzJyBzdGF0dXMsIHdoZXRoZXIgbWlsaXRhcnkgb3IgY2l2aWxpYW4uIEkgd2FudGVkIHRvIGRpc3BsYXkgdGhpcyByZWxhdGlvbnNoaXAgb3ZlciB0aGUgeWVhcnMuIEkgYmVsaWV2ZSB0aGUgbGluZSBwbG90IGlzIGEgZ29vZCBjaG9pY2UgdG8gaGlnaGxpZ2h0IHRoZSBhbHRlcm5hdGlvbiBvZiBhc3Ryb25hdXRzJyBzdGF0dXMsIGFsc28sIEkgd2FudGVkIHRvIHZhcnkuIEEgYmFyIHBsb3QgY291bGQgaGF2ZSBiZWVuIGEgZ29vZCBhbHRlcm5hdGl2ZS4KCioqRWRpdG9yIFN1Z2dlc3Rpb24qKiAgCkknZCBzdWdnZXN0IHRvIHB1Ymxpc2ggdGhlIG9uZSByZWdhcmRpbmcgdGhlIE1pciBzdG9yeS4gRmlyc3Qgb2YgYWxsLCBJIGNvbnNpZGVyIEVWIG1vcmUgaW50ZXJlc3RpbmcgdGhhbiB0aGUgYXN0cm9uYXV0cycgc3RhdHVzICh3aGljaCBpcyBub25ldGhlbGVzcyBpbnRlcmVzdGluZyBnaXZlbiB0aGUgcmVjZW50IHJpc2UgaW4gY2l2aWxpYW4gc3BhY2UgZXhwbG9yYXRpb24gbWlzc2lvbnMpLiBTZWNvbmRseSwgSSBiZWxpZXZlIHRoYXQgaW5jbHVkaW5nIGEgbGl0dGxlIGJpdCBvZiBoaXN0b3J5IG9mIHRoZSBzcGFjZSBleHBsb3JhdGlvbiBtaWdodCB0cmlnZ2VyIHRoZSByZWFkZXIgY3VyaW9zaXR5IGFib3V0IHRoZSB0b3BpYy4gSXQncyBtb3JlIGxpa2VseSB0byBiZSBhbiBpbnRlcmVzdGluZyBuZXcgbm90aW9uLgoKCl9fXwojIDUuIE1ha2UgdHdvIHBsb3RzIGludGVyYWN0aXZlCgpDaG9vc2UgMiBvZiB0aGUgcGxvdHMgeW91IGNyZWF0ZWQgYWJvdmUgYW5kIGFkZCBpbnRlcmFjdGl2aXR5LiBGb3IgYXQgbGVhc3Qgb25lIG9mIHRoZXNlIGludGVyYWN0aXZlIHBsb3RzLCB0aGlzIHNob3VsZCBub3QgYmUgZG9uZSB0aHJvdWdoIHRoZSB1c2Ugb2YgZ2dwbG90bHkuIEJyaWVmbHkgZGVzY3JpYmUgdG8gdGhlIGVkaXRvciB3aHkgaW50ZXJhY3Rpdml0eSBpbiB0aGVzZSB2aXN1YWxpemF0aW9ucyBpcyBwYXJ0aWN1bGFybHkgaGVscGZ1bCBmb3IgYSByZWFkZXIuCgojIyA1LjEgU3BhY2UgRXhsb3JhdGlvbiBNaXNzaW9uIEludGVyYWN0aXZlCmBgYHtyfQpnZ3Bsb3RseShwbHRfMSkKYGBgCgpJIHRoaW5rIHRoaXMgZ3JhcGggd2FzIHBlcmZlY3QgZm9yIGludGVyYWN0aXZpdHkuIEZpcnN0IG9mIGFsbCwgaXQgbWFrZXMgaXQgZWFzaWVyIGZvciB0aGUgcmVhZGVyIHRvIGdldCBpbmZvcm1hdGlvbiBmb3IgdGhlIGNvdW50cmllcyB0aGF0IGFyZSBub3QgcHJlZG9taW5hbnQuIFdpdGggaW50ZXJhY3Rpdml0eSwgb25lIGNhbiBlYXNpbHkgb2J0YWluIGluZm9ybWF0aW9uIGZvciB0aGUgY291bnRyaWVzIHRoYXQgYXJlIHVuZGVycmVwcmVzZW50ZWQuIFRoZW4sIGl0IG1ha2VzIGl0IGVhc2llciB0byB1bmRlcnN0YW5kIHRoZSB5ZWFyIHRvIHdoaWNoIHdlJ3JlIHJlZmVycmluZyBhbmQgcmV0cmlldmVzIHRoZSBleGFjdCBudW1iZXIgb2YgbWlzc2lvbnMgZm9yIHRoYXQgeWVhci4KCiMjIDUuMiBBc3Ryb25hdXRzIFN0YXR1cyBJbnRlcmFjdGl2ZQpgYGB7cn0KcGx0XzUuMiA8LSAKICB1bmdyb3VwKGFzdF9zdGF0dXMpICU+JQogIHBsb3RfbHkoeSA9IH5uLCB4ID0gfnllYXJfb2ZfbWlzc2lvbiwgY29sb3IgPSB+bWlsaXRhcnlfY2l2aWxpYW4sIHR5cGUgPSAic2NhdHRlciIsIG1vZGUgPSAibGluZXMiKSAlPiUKICBsYXlvdXQoCiAgICB0aXRsZSA9ICJBc3Ryb25hdXRzIHN0YXR1cyIsCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiWWVhciBvZiB0aGUgTWlzc2lvbiIpLCAKICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJOdW1iZXIgb2YgQXN0cm9uYXV0cyIpCiAgKQpwbHRfNS4yCmBgYAoKSSBiZWxpZXZlIHRoZSBpbnRlcmFjdGl2aXR5IG1ha2VzIGl0IGVhc2llciB0byBjb25mcm9udCB0aGUgaW5mb3JtYXRpb24gcHJlc2VudCBpbiB0aGlzIGdyYXBoLiBTaW5jZSB0aGUgcHVycG9zZSBvZiB0aGlzIGdyYXBoIGlzIGEgY29tcGFyaXNvbiwgd2l0aCB0aGUgY3Vyc29yIG9uZSBjYW4gZWFzaWx5IG1ha2UgY29tcGFyZSB0aGUgZXhhY3QgbnVtYmVyIGZvciB0aGUgdHdvIHN0YXR1c2VzIGJlaW5nIHN1cmUgdGhhdCBzaGUncyBjb25mcm9udGluZyB0aGUgc2FtZSB5ZWFyLgoKX19fCiMgNi4gRGF0YSBUYWJsZQoKVG8gYWxsb3cgdGhlIHJlYWRlciB0byBleHBsb3JlIHRoZSByZWNvcmQgaG9sZGluZyBhY2hpZXZlbWVudHMgb2YgYXN0cm9uYXV0cywgYWdncmVnYXRlIHRoZSBkYXRhIGJ5IGFzdHJvbmF1dC4gSW5jbHVkZSB0aGUgdG90YWwgbnVtYmVyIG9mIG1pc3Npb25zLCB0aGUgdG90YWwgbWlzc2lvbiB0aW1lLCBhbmQgYW55dGhpbmcgZWxzZSB5b3UgY29uc2lkZXIgdXNlZnVsIHRvIHNoYXJlIGFuZCBhZGQgYSBkYXRhIHRhYmxlIHRvIHRoZSBvdXRwdXQuIE1ha2Ugc3VyZSB0aGUgY29sdW1ucyBhcmUgY2xlYXJseSBsYWJlbGVkLiBTZWxlY3QgdGhlIGFwcHJvcHJpYXRlIG9wdGlvbnMgZm9yIHRoZSBkYXRhIHRhYmxlIChlLmcuIHNlYXJjaCBiYXIsIHNvcnRpbmcsIGNvbHVtbiBmaWx0ZXJzLCBpbi1saW5lIHZpc3VhbGl6YXRpb25zIGV0Yy4pLiBTdWdnZXN0IHRvIHRoZSBlZGl0b3Igd2hpY2gga2luZCBvZiBpbmZvcm1hdGlvbiB5b3Ugd291bGQgbGlrZSB0byBwcm92aWRlIGluIGEgZGF0YSB0YWJsZSBhbmQgd2h5LgoKIyMgNi4xIERhdGEgVGFibGUKYGBge3J9CmRhdGFfdGFibGUgPC0gZGYgJT4lCiAgc2VsZWN0KG5hbWUsIHNleCwgeWVhcl9vZl9iaXJ0aCwgbmF0aW9uYWxpdHksIHRvdGFsX251bWJlcl9vZl9taXNzaW9ucywgdG90YWxfaHJzX3N1bSwgdG90YWxfZXZhX2hycykgJT4lCiAgdW5pcXVlKCkgJT4lCiAgYXJyYW5nZShuYW1lKQpgYGAKCmBgYHtyfQpkYXRhdGFibGUoZGF0YV90YWJsZSwKICAgICAgICAgIGZpbHRlciA9ICd0b3AnLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUsIGF1dG9XaWR0aCA9IFRSVUUpLAogICAgICAgICAgY29sbmFtZXMgPSBjKCdOYW1lJywgJ1NleCcsICdZZWFyIG9mIEJpcnRoJywgJ05hdGlvbmFsaXR5JywgJ1RvdGFsIE51bWJlciBvZiBNaXNzaW9ucycsICdUb3RhbCBob3VycyBvZiBNaXNzaW9uJywgJ1RvdGFsIEV4dHJhIFZlaGljdWxhciBob3VycycpLAogICAgICAgICAgY2FwdGlvbiA9IGh0bWx0b29sczo6dGFncyRjYXB0aW9uKAogICAgc3R5bGUgPSAnY2FwdGlvbi1zaWRlOiBib3R0b207IHRleHQtYWxpZ246IGxlZnQ7JywgaHRtbHRvb2xzOjplbSgnU291cmNlOiBBc3Ryb25hdXQgRGF0YWJhc2UgKFN0YXZuaWNodWsgJiBDb3JsZXR0IDIwMjApJykKICAgICAgICAgICkKKQpgYGAKClRoZSBkYXRhIHRhYmxlIGlzIGV4dHJlbWVseSB1c2VmdWwgdG8gcmV0cmlldmUgaW5mb3JtYXRpb24uIFRoZSBmaWx0ZXIgb3B0aW9uLCBmb3IgZXhhbXBsZSwgaGVscHMgdGhlIHJlYWRlciB0byBuYXZpZ2F0ZSBhbmQgc2VsZWN0IGRhdGEgYWNjb3JkaW5nIHRvIGhpcyBpbnRlcmVzdC4gSWYgb25lIHdhbnRzIHRvIHJldHJpZXZlIGFsbCB0aGUgaXRhbGlhbiBhc3Ryb25hdXRzIG9mIHRoZSBkYXRhc2V0LCBzaGUgY2FuIGVhc2lseSB0eXBlICJJdGFseSIgdW5kZXIgdGhlIE5hdGlvbmFsaXR5IGNvbHVtbiwgYW5kIHRoZW4gcmVvcmdhbml6ZSB0aGUgZGF0YSB0byBoZXIgcHJlZmVyZW5jZS4gRm9yIGV4YW1wbGUsIHdoaWNoIGl0YWxpYW4gYXN0cm9uYXV0IGhhZCBtb3JlIG1pc3Npb24gaG91cnM/IFR5cGUgIkl0YWx5IiB1bmRlciB0aGUgTmF0aW9uYWxpdHkgY29sdW1uIGFuZCB0aGVuIHJlb3JnYW5pemUgYnkgIlRvdGFsIGhvdXJzIG9mIE1pc3Npb24uIgoKVGhpcyBkYXRhIHRhYmxlIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBOYW1lLCBTZXgsIFllYXIgb2YgQmlydGgsIE5hdGlvbmFsaXR5LCBUb3RhbCBOdW1iZXIgb2YgTWlzc2lvbiwgVG90YWwgaG91cnMgb2YgTWlzc2lvbiwgVG90YWwgRXRyYSBWZWhpY3VsYXIgaG91cnMsIGZvciBhbGwgYXN0cm9uYXV0cyBwcmVzZW50IGluIHRoZSBkYXRhc2V0Lg==